home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Sample Code / Snippets / Networking / ADSP Chat / Atalk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  19.1 KB  |  695 lines  |  [TEXT/MPS ]

  1. /*****************************************************************
  2.  
  3.     Program:    < ADSP Chat >
  4.     File:        < Atalk.c >
  5.     
  6.     Written by  Pete Helm, Scott Kuechle
  7.     of <Apple Macintosh Developer Technical Support>
  8.     
  9.     modified by Scott Kuechle
  10.     10/92 SRK Converted from Pascal to C
  11.     8/94 SRK Modified to use a queue of parameter
  12.              blocks.
  13.  
  14.     Copyright © 1992, 1994 Apple Computer, Inc.
  15.     All rights reserved.
  16.     
  17. *****************************************************************/
  18.  
  19.  
  20. /*****************************************************************/
  21. /*  I N C L U D E S
  22. /*****************************************************************/
  23.  
  24. #include    "ADSP Chat.h"
  25.  
  26.  
  27. /********************************************************************
  28. /*  G L O B A L   V A R I A B L E   D E C L A R A T I O N S
  29. /********************************************************************/
  30.  
  31.  
  32. ATPPBPtr        gATPPBPtr;            /* the parameter block for GetZoneList call */
  33. XPPParmBlkPtr    gXPBPBPtr;            /* structure for Phase 2 NBP lookups */
  34. short            xppDriverRefNum;
  35. Str255             gZoneString, gObjStr, gTypeStr;
  36. Str32             myName;
  37. NamesTableEntry myNTE;
  38. AddrBlock         theBridgeAddress, ourNetworkAddress;
  39.  
  40.  
  41. /*****************************************************************/
  42. /*
  43. /* E X T E R N A L S
  44. /*
  45. /*****************************************************************/
  46.  
  47. extern SysEnvRec    gMac;                /* set up by Initialize */
  48. extern char         myLocalSocket;
  49.  
  50. extern void         ShowError(short index);
  51. extern void         CopyPstr(Ptr pSource, Ptr pDest);
  52. extern void         Terminate();
  53. extern void            Exit(short message);
  54. extern qsort (Ptr base, long n, long size, ProcPtr compare);
  55.  
  56.  
  57.  
  58. /*****************************************************************/
  59. /*
  60. /* R O U T I N E S
  61. /*
  62. /*****************************************************************/
  63.  
  64. Boolean registerMyName();
  65. void     removeMyName();
  66. long     myCompare (Str255 aStr, Str255 bStr);
  67. void     letsSort (Ptr theBuffPtr, long numZonesGot);
  68. void     addZonesToBuffer (Ptr LkUpBuffer,
  69.                 Ptr BufferForZoneMenu,
  70.                 short NumZonesGot,
  71.                 short CurrentTotal);
  72. void     parseItemsAddToMenu (Ptr theBuffPtr,
  73.                     MenuHandle zoneMenu,
  74.                     short NumZonesGot);;
  75. Boolean zonesPresent();
  76. void     parseLkupBuffAddToMenu (Ptr theBuffPtr,
  77.                         Ptr bigBuffer,
  78.                         MenuHandle lookupMenu,
  79.                         short NumGot,
  80.                         Boolean doObjects);
  81. void     LookupNames (MenuHandle lookupMenu,
  82.                 Boolean doObjects);
  83. void     BuildZoneListPhase1(MenuHandle zoneMenu);
  84. void     BuildZoneListPhase2(MenuHandle zoneMenu);
  85. void     GetZones(MenuHandle ZoneMenu);
  86. void     getOurZonePhase2();
  87. void     getOurZonePhase1();
  88. OSErr     InitAppleTalk();
  89. void     GetOurZone();
  90.  
  91.  
  92. #pragma segment Main
  93. // *****************************************************************
  94. // *    registerMyName
  95. // *
  96. // *    registers our nbp name on the network so we can find other
  97. // *    machines that are running our application.
  98. // *****************************************************************
  99. Boolean registerMyName()
  100. {
  101.     MPPParamBlock pb;
  102.     StringHandle userName;
  103.     
  104.  
  105.         userName = GetString(-16096);
  106.  
  107.         myName[0] = 0;
  108.         if (userName != nil)
  109.         {
  110.             if (*userName[0] != 0)
  111.                 BlockMove(*userName,&myName,*userName[0]+1);
  112.         }
  113.         
  114.  
  115.         NBPSetNTE((Ptr)&myNTE, &myName, "\pMoof", "\p*", myLocalSocket);
  116.     
  117.         pb.NBP.interval = 2;
  118.         pb.NBP.count = 3;
  119.         pb.NBP.NBPPtrs.entityPtr = (Ptr)&myNTE;
  120.         pb.NBP.parm.verifyFlag = 1;
  121.         if (PRegisterName(&pb,false) != noErr)
  122.         {
  123.             ShowError(nbpErr);
  124.             return false;
  125.         }
  126.         
  127.         return true;
  128. }
  129.  
  130. // *****************************************************************
  131. // *    removeMyName
  132. // *
  133. // *    removes our nbp name from the network.
  134. // *****************************************************************
  135. void removeMyName()
  136. {
  137.     MPPParamBlock pb;
  138.     OSErr err;
  139.  
  140.         pb.NBP.NBPPtrs.entityPtr = (Ptr)&myNTE.nt.entityData;
  141.         
  142.         err = PRemoveName(&pb, false);
  143. }
  144.  
  145.  
  146.  
  147. // *****************************************************************
  148. // *    myCompare
  149. // *
  150. // *    this uses stand International Utilites package for sorting
  151. // *****************************************************************
  152. long myCompare (Str255 aStr, Str255 bStr)
  153.     {
  154.         return ((long)IUCompString(bStr, aStr));
  155.     }
  156.  
  157.  
  158. // *****************************************************************
  159. // *    letsSort
  160. // *
  161. // * calls a standard C qSort routine compiled with Pascal calling 
  162. // * conventions the 33 is the standard size of a Str32 type, which
  163. // * is the standard size of an AppleTalk NBP object.
  164. // *****************************************************************
  165. void letsSort (Ptr theBuffPtr, long numZonesGot)
  166.     {
  167.         qsort(theBuffPtr, numZonesGot, 33, &myCompare);
  168.     }
  169.  
  170. // *****************************************************************
  171. // *    addZonesToBuffer
  172. // *
  173. // *    
  174. // *****************************************************************
  175. void addZonesToBuffer (Ptr LkUpBuffer,
  176.                 Ptr BufferForZoneMenu,
  177.                 short NumZonesGot,
  178.                 short CurrentTotal)
  179. {    
  180.     char curLength;
  181.     long index;
  182.     short i;
  183.  
  184.         index = 0;
  185.         curLength = 0;
  186.         for (i=CurrentTotal;i<=(NumZonesGot + CurrentTotal) && (i < maxZones);++i)
  187.         {
  188.             curLength = *(LkUpBuffer + index);
  189.             BlockMove((LkUpBuffer + index), (BufferForZoneMenu + (i * 33)), 33);
  190.             index = index + curLength + 1;
  191.         }
  192. }
  193.  
  194. // *****************************************************************
  195. // *    parseItemsAddToMenu
  196. // *
  197. // *    this routine adds zone name items to our zones popup menu
  198. // *****************************************************************
  199. void parseItemsAddToMenu (Ptr theBuffPtr,
  200.                     MenuHandle zoneMenu,
  201.                     short NumZonesGot)
  202. {    
  203.     long index;
  204.     Str255 tempString;
  205.     short i;
  206.  
  207.         letsSort(theBuffPtr, NumZonesGot);
  208.     
  209.         index = 0;
  210.         for (i=0; i<=(NumZonesGot - 1); ++i)
  211.             {
  212.                 BlockMove((theBuffPtr + i * 33), &tempString, 33);
  213.                     /* initially insert a blank item so meta-characters aren't used */
  214.                 AppendMenu(zoneMenu, "\p ");
  215.                     /* use SetItem so we can display meta-chars in zone names */
  216.                 SetItem(zoneMenu, i + 1, tempString);
  217.     
  218.             }
  219. }
  220.  
  221. // *****************************************************************
  222. // *    zonesPresent
  223. // *
  224. // * this checks to see if there is a local bridge available
  225. // *****************************************************************
  226. Boolean zonesPresent()
  227. {    
  228.     short myNode,ignore;
  229.  
  230.  
  231.         theBridgeAddress.aNode = 0;
  232.     
  233.         theBridgeAddress.aNode = GetBridgeAddress();
  234.         ignore = GetNodeAddress(&myNode, &ourNetworkAddress.aNet);
  235.     
  236.         ourNetworkAddress.aNode = myNode;
  237.         theBridgeAddress.aNet = ourNetworkAddress.aNet;
  238.         
  239.         if (ourNetworkAddress.aNode != 0) 
  240.         {
  241.             theBridgeAddress.aSocket = theBridgeSocket;
  242.             return true;
  243.         }
  244.         else
  245.         {
  246.             CopyPstr("\p*", &gZoneString);
  247.             return false;
  248.         }
  249. }
  250.  
  251.  
  252.  
  253. // *****************************************************************
  254. // *    parseLkupBuffAddToMenu
  255. // *
  256. // *    this routine takes all the names returned from the nbp lookup
  257. // *    and checks to see if the item is already in the list. If not,
  258. // *    the item is added to the appropriate popup menu.
  259. // *****************************************************************
  260. void parseLkupBuffAddToMenu (Ptr NamesReturnedBuffer,        /* lookup buffer where names were returned */
  261.                         Ptr NonDuplicateNamesBuffer,        /* check for duplicates then store all names here */
  262.                         MenuHandle lookupMenu,
  263.                         short NumGot,                        /* number of items returned in this lookup */
  264.                         Boolean doObjects)                    /* flag - are we saving nbp type or object items? */
  265. {    
  266.     Str255 menuString, str;
  267.     short i, j, k;
  268.     EntityName abEntity;
  269.     AddrBlock address;
  270.     OSErr resultCode;
  271.     Boolean weHaveDupe;
  272.  
  273.  
  274.         k = 1;
  275.         for (i=1; i<=NumGot; ++i)
  276.         {
  277.                 /* get an item from the list */
  278.             resultCode = NBPExtract(NamesReturnedBuffer, NumGot, i, &abEntity, &address);
  279.                 /* save off current item */
  280.             if (doObjects)    /* do object strings */
  281.                 BlockMove(&abEntity.objStr,&menuString,abEntity.objStr[0]+1);
  282.             else    /* do type strings */
  283.                 BlockMove(&abEntity.typeStr,&menuString,abEntity.typeStr[0]+1);
  284.  
  285.                 /* check for duplicates here */
  286.             weHaveDupe = false;
  287.             j = 0;
  288.             do
  289.             {
  290.                 j = j + 1;
  291.                 BlockMove((NonDuplicateNamesBuffer + (j - 1) * 33), &str, 33);
  292.                     /* do we already have this item in the list? */
  293.                 if (EqualString(str, menuString, false, true))
  294.                     weHaveDupe = true;
  295.             }
  296.             while ((j <= k) && (weHaveDupe == false));
  297.  
  298.                 /* if we dont have a duplicate item and if the item is not our own node (we dont
  299.                     support self-send) then add it to our list */
  300.             if ((weHaveDupe == false) && (address != ourNetworkAddress))
  301.             {
  302.                 BlockMove(&menuString, (NonDuplicateNamesBuffer + (k - 1) * 33), 33);
  303.                 k = k + 1;
  304.             }
  305.         }
  306.         
  307.             /* now put all our new items into the actual menu */
  308.         parseItemsAddToMenu(NonDuplicateNamesBuffer, lookupMenu, k - 1);
  309. }
  310.  
  311. // *****************************************************************
  312. // *    LookupNames
  313. // *
  314. // *    issues an nbp lookup for the desired object, type and zone
  315. // *    the user has specified with the target machine popup menus.
  316. // *****************************************************************
  317. void LookupNames (MenuHandle lookupMenu,
  318.                 Boolean doObjects)            /* flag - do we want nbp type or object items? */
  319. {    
  320.     Str32 NBPObject, NBPType, NBPZone;
  321.     NamesTableEntry lookupEntity;
  322.     Ptr NBPLookupBuffer;                     /* totally gross mondo buffer for returned names */
  323.     Ptr NonDuplicateNamesBuffer;            /* put all non-duplicate into this buffer */
  324.     MPPParamBlock pbLKP;
  325.  
  326.         NBPLookupBuffer = nil;
  327.         NonDuplicateNamesBuffer = nil;
  328.         
  329.         NBPLookupBuffer = NewPtr(BigLookupBuffer);
  330.         if (NBPLookupBuffer == nil)
  331.             return;
  332.  
  333.         NonDuplicateNamesBuffer = NewPtr(NameBufSize);
  334.         if (NonDuplicateNamesBuffer == nil)
  335.             goto Exit;
  336.  
  337.         CopyPstr("\p=", NBPObject);
  338.  
  339.         if (!doObjects)
  340.             CopyPstr("\p=", NBPType);
  341.         else
  342.             BlockMove(&gTypeStr,&NBPType,gTypeStr[0]+1);
  343.  
  344.         if (zonesPresent()) 
  345.             BlockMove(&gZoneString,&NBPZone,gZoneString[0]+1);
  346.         else
  347.             CopyPstr("\p*", NBPZone);
  348.  
  349.         NBPSetEntity((Ptr)&lookupEntity.nt.entityData, NBPObject, NBPType, NBPZone);
  350.  
  351.         pbLKP.NBP.ioCompletion = nil;
  352.         pbLKP.NBP.interval = 3;
  353.         pbLKP.NBP.count = 3;
  354.         pbLKP.NBPentityPtr = &lookupEntity.nt.entityData;
  355.         pbLKP.NBPretBuffSize = BigLookupBuffer;
  356.         pbLKP.NBPretBuffPtr = NBPLookupBuffer;
  357.         pbLKP.NBPmaxToGet = (BigLookupBuffer/sizeof(NTElement));
  358.  
  359.         if (PLookupName(&pbLKP, false) == noErr)
  360.             if (pbLKP.NBPnumGotten > 0)
  361.                 parseLkupBuffAddToMenu(NBPLookupBuffer, NonDuplicateNamesBuffer, lookupMenu, pbLKP.NBPnumGotten, doObjects);
  362.  
  363. Exit:
  364.         if (NBPLookupBuffer != nil)
  365.             DisposPtr(NBPLookupBuffer);
  366.             
  367.         if (NonDuplicateNamesBuffer != nil)
  368.             DisposPtr(NonDuplicateNamesBuffer);
  369.  
  370. }
  371.  
  372.  
  373.  
  374. // *****************************************************************
  375. // *    BuildZoneListPhase1
  376. // *
  377. // *    Create the list of zones on the network. Find a bridge to talk to , if one is
  378. // *     present, then ask it for zone names. Add the names to the list in the dialog.
  379. // *****************************************************************
  380. void BuildZoneListPhase1(MenuHandle zoneMenu)
  381. {
  382.     BDSElement    dBDS;                /* the BDS for GetZoneList call */
  383.     ATPPBPtr    gATPPBPtr;
  384.     Ptr            gZones,sortBuffer;
  385.     long        tempUserData;
  386.     short        zIndex,zoneCallType;
  387.     Boolean        DontGetMoreZones;
  388.     short        NumZonesGot, totalZones;
  389.     
  390.  
  391.         
  392.         gATPPBPtr = nil;                                            /* init some important variables*/
  393.         gZones = nil;
  394.         sortBuffer = nil;
  395.     
  396.         if (zonesPresent() == false)
  397.             return;
  398.     
  399.         gATPPBPtr = (ATPPBPtr)NewPtr(sizeof(ATPParamBlock));
  400.         if (gATPPBPtr == nil)
  401.             return;
  402.             
  403.         gZones = NewPtr(kZonesSize);
  404.         if (gZones == nil)
  405.             goto Exit;
  406.             
  407.         sortBuffer = NewPtr(ZoneBufSize);
  408.         if (sortBuffer == nil)
  409.             goto Exit;
  410.  
  411.         zoneCallType = kGetZoneList;
  412.         zIndex = 1;
  413.             
  414.         dBDS.buffSize = kZonesSize;                                    /* set up BDS */
  415.         dBDS.buffPtr = gZones;
  416.         dBDS.dataSize = 0;
  417.         dBDS.userBytes = 0;
  418.     
  419.         gATPPBPtr->ATPatpFlags = 0;
  420.  
  421.     
  422.         gATPPBPtr->ATPaddrBlock.aNet = theBridgeAddress.aNet;
  423.         gATPPBPtr->ATPaddrBlock.aNode = theBridgeAddress.aNode;        /* get node of bridge */
  424.         gATPPBPtr->ATPaddrBlock.aSocket = kZIPSocket;                /* the socket we want */
  425.         gATPPBPtr->ATPreqLength = 0;
  426.         gATPPBPtr->ATPreqPointer = nil;
  427.         gATPPBPtr->ATPbdsPointer = (Ptr) &dBDS;
  428.         gATPPBPtr->ATPnumOfBuffs = 1;
  429.         gATPPBPtr->ATPtimeOutVal = kATPTimeOutVal;
  430.         gATPPBPtr->ATPretryCount = kATPRetryCount;
  431.     
  432.         NumZonesGot = 0;
  433.         totalZones = 0;
  434.         DontGetMoreZones = false;
  435.     
  436.             /* keep going until none left (and we haven't exceeded our buffer size) */
  437.         while (!DontGetMoreZones && (totalZones <= maxZones)) 
  438.         {
  439.             zIndex += NumZonesGot;            /* index count. 1 for start */
  440.  
  441.             BlockMove((Ptr) &zoneCallType + 1, (Ptr) &tempUserData, 1L);
  442.             BlockMove((Ptr) &zIndex, (Ptr)&tempUserData + 2, 2L);
  443.  
  444.             gATPPBPtr->ATPuserData = tempUserData;                        /* indicate GetZoneList request */
  445.             
  446.             if (PSendRequest(gATPPBPtr, false) != noErr)        /* send sync request */
  447.                 Exit(DrvrErr);
  448.             
  449.             tempUserData = dBDS.userBytes;
  450.             BlockMove((Ptr) &tempUserData, (Ptr) &DontGetMoreZones, 1); /* the highbyte will be nonzero if its the last packet of zones */
  451.             BlockMove((Ptr)&tempUserData + 2, (Ptr) &NumZonesGot, 2);
  452.     
  453.             addZonesToBuffer(dBDS.buffPtr,sortBuffer,NumZonesGot,totalZones);            
  454.  
  455.             totalZones += NumZonesGot;
  456.         }
  457.  
  458.         totalZones = (totalZones <= maxZones) ? totalZones : maxZones;
  459.         parseItemsAddToMenu(sortBuffer,zoneMenu,totalZones);
  460.  
  461.         Exit:
  462.             if (gATPPBPtr != nil)
  463.                 DisposePtr((Ptr)gATPPBPtr);
  464.             if (gZones != nil)
  465.                 DisposePtr(gZones);
  466.             if (sortBuffer != nil)
  467.                 DisposePtr(sortBuffer);
  468.  
  469. } /* BuildZoneList */
  470.  
  471. // *****************************************************************
  472. // *    BuildZoneListPhase2
  473. // *
  474. // *    Create the list of zones on the network. Find a bridge to talk to , if one is
  475. // *     present, then ask it for zone names. Add the names to the list in the dialog.
  476. // *****************************************************************
  477. void BuildZoneListPhase2(MenuHandle zoneMenu)
  478. {
  479.     Ptr            bigBuffer;
  480.     short        TotalZones;
  481.     Ptr            gZones;     /* the data buffer for GetZoneList call */
  482.  
  483.  
  484.         gXPBPBPtr = nil;                                            /* init some important variables*/
  485.         gZones = nil;
  486.         bigBuffer = nil;
  487.     
  488.     
  489.         if (zonesPresent() == false)
  490.             return;
  491.     
  492.         gXPBPBPtr = (XPPParmBlkPtr)NewPtr(sizeof(XCallParam));
  493.         if (gXPBPBPtr == nil)
  494.             return;
  495.         
  496.         gZones = NewPtr(kZonesSize);
  497.         if (gZones == nil)
  498.             goto Exit;
  499.     
  500.             /* big, ugly mondo buffer to hold complete zone list so we can sort them */
  501.         bigBuffer = NewPtr(ZoneBufSize);
  502.         if (bigBuffer == nil)
  503.             goto Exit;
  504.     
  505.         gXPBPBPtr->XCALL.zipInfoField[0] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  506.         gXPBPBPtr->XCALL.zipInfoField[1] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  507.         gXPBPBPtr->XCALL.zipLastFlag = 0;
  508.     
  509.         gXPBPBPtr->XCALL.ioRefNum = xppDriverRefNum;
  510.         gXPBPBPtr->XCALL.csCode = xCall;
  511.         gXPBPBPtr->XCALL.xppSubCode = zipGetZoneList;
  512.         gXPBPBPtr->XCALL.xppTimeout = kATPTimeOutVal;
  513.         gXPBPBPtr->XCALL.xppRetry = kATPRetryCount;
  514.         gXPBPBPtr->XCALL.zipBuffPtr = (Ptr) gZones;
  515.     
  516.         TotalZones = 0;
  517.     
  518.         do
  519.         {
  520.             if (PBControl((ParmBlkPtr) gXPBPBPtr, false) != noErr)
  521.                 Exit(DrvrErr);
  522.  
  523.             addZonesToBuffer(gZones,bigBuffer,gXPBPBPtr->XCALL.zipNumZones,TotalZones);
  524.             TotalZones = TotalZones + gXPBPBPtr->XCALL.zipNumZones;                        /* find out how many returned */
  525.     
  526.         } while ((gXPBPBPtr->XCALL.zipLastFlag == 0) && (TotalZones <= maxZones));                /*     keep going until none left */
  527.         
  528.         TotalZones = (TotalZones <= maxZones) ? TotalZones : maxZones;
  529.         parseItemsAddToMenu(bigBuffer,zoneMenu,TotalZones);
  530.     
  531.     Exit:
  532.     
  533.         if (gXPBPBPtr != nil)
  534.             DisposPtr((Ptr)gXPBPBPtr);            /* get rid of pb block */
  535.     
  536.         if (gZones != nil)
  537.             DisposPtr(gZones);                    /* and buffer */
  538.     
  539.         if (bigBuffer != nil)
  540.             DisposPtr(bigBuffer);                    /* and buffer */
  541.  
  542. } /* BuildZoneList */
  543.  
  544. // *****************************************************************
  545. // *    GetZones
  546. // *
  547. // *    checks which version of AppleTalk we are using and then calls
  548. // *     the appropriate routine for building the zone list.
  549. // *****************************************************************
  550. void GetZones(MenuHandle ZoneMenu)
  551. {
  552.         /* are we using AppleTalk Phase 1 or 2 ? */
  553.     if(gMac.atDrvrVersNum > 52)
  554.         BuildZoneListPhase2(ZoneMenu);            /*    put the stuff into the list */
  555.     else
  556.         BuildZoneListPhase1(ZoneMenu);            /*    put the stuff into the list */
  557. }
  558.  
  559.  
  560. #pragma segment Initialize
  561. // *****************************************************************
  562. // *    getOurZonePhase2
  563. // *
  564. // *    gets our local zone using AppleTalk Phase 2 calls
  565. // *****************************************************************
  566. void getOurZonePhase2()
  567. {
  568.  
  569.     gXPBPBPtr = nil;            /* init some important variables*/
  570.     gZoneString[0] = 0;
  571.  
  572.  
  573.     if (zonesPresent() == false)
  574.         return;
  575.     
  576.     gXPBPBPtr = (XPPParmBlkPtr)NewPtr(sizeof(XCallParam));
  577.     if (gXPBPBPtr == nil)
  578.         return;
  579.  
  580.     gXPBPBPtr->XCALL.zipInfoField[0] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  581.     gXPBPBPtr->XCALL.zipInfoField[1] = 0;    /* ALWAYS 0 on first call.  has state info on subsequent calls */
  582.     gXPBPBPtr->XCALL.zipLastFlag = 0;
  583.  
  584.     gXPBPBPtr->XCALL.ioRefNum = xppDriverRefNum;
  585.     gXPBPBPtr->XCALL.csCode = xCall;
  586.     gXPBPBPtr->XCALL.xppSubCode = zipGetMyZone;
  587.     gXPBPBPtr->XCALL.xppTimeout = kATPTimeOutVal;
  588.     gXPBPBPtr->XCALL.xppRetry = kATPRetryCount;
  589.     gXPBPBPtr->XCALL.zipBuffPtr = (Ptr)&gZoneString;
  590.  
  591.     if (PBControl((ParmBlkPtr) gXPBPBPtr, false) != noErr)        /* send sync control call */
  592.         Exit(DrvrErr);
  593.  
  594.     DisposPtr((Ptr)gXPBPBPtr);            /* get rid of pb block */
  595.     
  596. }
  597.  
  598.  
  599. // *****************************************************************
  600. // *    getOurZonePhase1
  601. // *
  602. // *    gets our local zone using AppleTalk Phase 1 calls
  603. // *****************************************************************
  604. void getOurZonePhase1()
  605. {    
  606.     BDSElement myZoneBDS;
  607.     ATPParamBlock ZonePB;
  608.     long tempUserData;
  609.     Ptr theBufferPtr;
  610.     char zoneCallType;
  611.  
  612.         zoneCallType = 7;  /*8 for zone list   7 returns my zone */
  613.         theBufferPtr = nil;
  614.         gZoneString[0] = 0;
  615.  
  616.         
  617.         if (zonesPresent() == true)
  618.         {
  619.             theBufferPtr = NewPtr(33);
  620.             if (theBufferPtr != nil) 
  621.             {
  622.                 myZoneBDS.buffSize = 33;
  623.                 myZoneBDS.buffPtr = theBufferPtr;
  624.                 myZoneBDS.dataSize = 0;
  625.                 myZoneBDS.userBytes = 0;
  626.  
  627.                 ZonePB.ATP.atpFlags = 0;
  628.                 ZonePB.ATP.ioCompletion = nil;
  629.  
  630.                 ZonePB.ATP.userData = 0;/*  ATP user data  */
  631.                 ZonePB.ATP.addrBlock = theBridgeAddress;
  632.                 ZonePB.ATP.reqLength = 0;
  633.                 ZonePB.ATP.reqPointer = nil;
  634.                 ZonePB.ATP.bdsPointer = (Ptr)&myZoneBDS;
  635.                 ZonePB.ATPnumOfBuffs = 1;
  636.                 ZonePB.ATPtimeOutVal = 2;
  637.                 ZonePB.ATPretryCount = 3;
  638.  
  639.                 /* 0 this out so bottom three bytes are 0 */
  640.                 tempUserData = 0;
  641.                 BlockMove(&zoneCallType, (Ptr)&tempUserData, 1);
  642.  
  643.                 ZonePB.ATP.userData = tempUserData;
  644.  
  645.                 gZoneString[0] = 0;
  646.                 if (PSendRequest(&ZonePB, false) == noErr) 
  647.                 {
  648.                     BlockMove(myZoneBDS.buffPtr, &gZoneString, 33);
  649.                 }
  650.                 DisposPtr(theBufferPtr);
  651.             }
  652.         }
  653. }
  654.  
  655.  
  656. // *****************************************************************
  657. // *    InitAppleTalk
  658. // *
  659. // *    opens the appropriate AppleTalk drivers
  660. // *****************************************************************
  661. OSErr InitAppleTalk()
  662. {
  663.     OSErr err;
  664.     short ref;
  665.     
  666.         if (gMac.atDrvrVersNum > 52)
  667.         {
  668.             err = OpenDriver("\p.MPP",&ref);
  669.             if (err != noErr)
  670.                 return err;
  671.     
  672.             err = OpenDriver("\p.XPP",&xppDriverRefNum);
  673.         }
  674.         else
  675.             err = MPPOpen();
  676.     
  677.         return err;
  678.     
  679. }
  680.  
  681. // *****************************************************************
  682. // *    GetOurZone
  683. // *
  684. // *    checks which version of AppleTalk we are using and then calls
  685. // *    the appropriate phase 1 or phase 2 call to get the local zone.
  686. // *****************************************************************
  687. void GetOurZone()
  688. {
  689.     if(gMac.atDrvrVersNum > 52)
  690.         getOurZonePhase2();                                    /*    put the stuff into the list */
  691.     else
  692.         getOurZonePhase1();                                    /*    put the stuff into the list */
  693.  
  694. }
  695.